From bcb3aec8347a3bf72e1cf711394d5228a2ff8a0c Mon Sep 17 00:00:00 2001 From: "mjw@wray-m-3.hpl.hp.com" Date: Wed, 14 Jul 2004 10:40:26 +0000 Subject: [PATCH] bitkeeper revision 1.1080 (40f50d9aaH0Dd_smhBdPvYcIQFbsoA) Improved error handling in xend and XendClient. --- .rootkeys | 1 + tools/python/xen/xend/XendClient.py | 8 ++- tools/python/xen/xend/XendDomain.py | 9 +-- tools/python/xen/xend/XendDomainInfo.py | 16 ++--- tools/python/xen/xend/XendError.py | 14 ++++ tools/python/xen/xend/server/SrvBase.py | 65 +++++++++++++++---- tools/python/xen/xend/server/SrvConsole.py | 29 +++++---- tools/python/xen/xend/server/SrvConsoleDir.py | 25 +++---- tools/python/xen/xend/server/SrvDaemon.py | 19 +++--- tools/python/xen/xend/server/SrvDir.py | 44 +++++++++---- tools/python/xen/xend/server/SrvDmesg.py | 23 ++++--- tools/python/xen/xend/server/SrvDomain.py | 11 +--- tools/python/xen/xend/server/SrvDomainDir.py | 54 ++++++++------- tools/python/xen/xend/server/SrvNode.py | 35 +++++----- tools/python/xen/xend/server/domain.py | 4 +- tools/python/xen/xend/server/netif.py | 5 +- 16 files changed, 223 insertions(+), 139 deletions(-) create mode 100644 tools/python/xen/xend/XendError.py diff --git a/.rootkeys b/.rootkeys index 812f49c65a..f11d07c06a 100644 --- a/.rootkeys +++ b/.rootkeys @@ -240,6 +240,7 @@ 40c9c468fSl3H3IypyT0ppkbb0ZT9A tools/python/xen/xend/XendDomain.py 40c9c468bbKq3uC7_fuNUkiMMjArdw tools/python/xen/xend/XendDomainConfig.py 40c9c4685ykq87_n1kVUbMr9flx9fg tools/python/xen/xend/XendDomainInfo.py +40f50d99YiiaMI1fZBh1VCDFLD57qg tools/python/xen/xend/XendError.py 40c9c46854nsHmuxHQHncKk5rAs5NA tools/python/xen/xend/XendMigrate.py 40c9c468M96gA1EYDvNa5w5kQNYLFA tools/python/xen/xend/XendNode.py 40c9c4686jruMyZIqiaZRMiMoqMJtg tools/python/xen/xend/XendRoot.py diff --git a/tools/python/xen/xend/XendClient.py b/tools/python/xen/xend/XendClient.py index e412c1e749..91ba071dc0 100644 --- a/tools/python/xen/xend/XendClient.py +++ b/tools/python/xen/xend/XendClient.py @@ -13,6 +13,8 @@ import types from StringIO import StringIO import urlparse +from twisted.protocols import http + from encode import * import sxp import PrettyPrint @@ -121,9 +123,9 @@ def xend_request(url, method, data=None): resp = conn.getresponse() if DEBUG: print resp.status, resp.reason if DEBUG: print resp.msg.headers - if resp.status in [204, 404]: + if resp.status in [ http.NO_CONTENT ]: return None - if resp.status not in [200, 201, 202, 203]: + if resp.status not in [ http.OK, http.CREATED, http.ACCEPTED ]: raise XendError(resp.reason) pin = sxp.Parser() data = resp.read() @@ -135,7 +137,7 @@ def xend_request(url, method, data=None): val = pin.get_val() #if isinstance(val, types.ListType) and sxp.name(val) == 'val': # val = val[1] - if isinstance(val, types.ListType) and sxp.name(val) == 'err': + if isinstance(val, types.ListType) and sxp.name(val) == 'xend.err': raise XendError(val[1]) if DEBUG: print '**val='; sxp.show(val); print return val diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index a7877bd6cf..6715b57f6a 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -21,6 +21,7 @@ import XendDomainInfo import XendConsole import XendMigrate import EventServer +from XendError import XendError from xen.xend.server import SrvDaemon xend = SrvDaemon.instance() @@ -324,9 +325,9 @@ class XendDomain: dom = int(id) dominfo = self.domain_get(dom) if not dominfo: - raise ValueError("Invalid domain: " + str(id)) + raise XendError("Invalid domain: " + str(id)) if dominfo.config: - raise ValueError("Domain already configured: " + str(id)) + raise XendError("Domain already configured: " + str(id)) def fn(dominfo): self._add_domain(dominfo.id, dominfo) return dominfo @@ -575,7 +576,7 @@ class XendDomain: dom = int(dom) dominfo = self.domain_get(dom) if not dominfo: - raise ValueError("invalid domain:" + str(dom)) + raise XendError("invalid domain:" + str(dom)) self.refresh_schedule() return dominfo.device_create(devconfig) @@ -589,7 +590,7 @@ class XendDomain: dom = int(dom) dominfo = self.domain_get(dom) if not dominfo: - raise ValueError("invalid domain:" + str(dom)) + raise XendError("invalid domain:" + str(dom)) self.refresh_schedule() return dominfo.device_destroy(type, idx) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index a9c4f5b492..be7803f721 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -29,6 +29,8 @@ xendConsole = XendConsole.instance() import server.SrvDaemon xend = server.SrvDaemon.instance() +from XendError import VmError + """Flag for a block device backend domain.""" SIF_BLK_BE_DOMAIN = (1<<4) @@ -58,16 +60,6 @@ def shutdown_reason(code): """ return shutdown_reasons.get(code, "?") -class VmError(ValueError): - """Vm construction error.""" - - def __init__(self, value): - self.value = value - - def __str__(self): - return self.value - - def blkdev_name_to_number(name): """Take the given textual block-device name (e.g., '/dev/sda1', 'hda') and return the device number used by the OS. """ @@ -410,7 +402,11 @@ class XendDomainInfo: self.autorestart = 1 self.configure_backends() image = sxp.child_value(config, 'image') + if image is None: + raise VmError('missing image') image_name = sxp.name(image) + if image_name is None: + raise VmError('missing image name') image_handler = get_image_handler(image_name) if image_handler is None: raise VmError('unknown image type: ' + image_name) diff --git a/tools/python/xen/xend/XendError.py b/tools/python/xen/xend/XendError.py new file mode 100644 index 0000000000..0e6c75ebb7 --- /dev/null +++ b/tools/python/xen/xend/XendError.py @@ -0,0 +1,14 @@ + +class XendError(ValueError): + + def __init__(self, value): + self.value = value + + def __str__(self): + return self.value + +class VmError(XendError): + """Vm construction error.""" + + pass + diff --git a/tools/python/xen/xend/server/SrvBase.py b/tools/python/xen/xend/server/SrvBase.py index 6ea92ae6cc..048339e0b4 100644 --- a/tools/python/xen/xend/server/SrvBase.py +++ b/tools/python/xen/xend/server/SrvBase.py @@ -10,12 +10,15 @@ import StringIO from twisted.internet import defer #defer.Deferred.debug = 1 from twisted.internet import reactor +from twisted.protocols import http from twisted.web import error from twisted.web import resource from twisted.web import server from xen.xend import sxp from xen.xend import PrettyPrint +from xen.xend.Args import ArgError +from xen.xend.XendError import XendError def uri_pathlist(p): """Split a path into a list. @@ -86,33 +89,45 @@ class SrvBase(resource.Resource): """ op = req.args.get('op') if op is None or len(op) != 1: - req.setResponseCode(404, "Invalid") + req.setResponseCode(http.NOT_ACCEPTABLE, "Invalid request") return '' op = op[0] op_method = self.get_op_method(op) if op_method is None: - req.setResponseCode(501, "Not implemented") + req.setResponseCode(http.NOT_IMPLEMENTED, "Operation not implemented: " + op) req.setHeader("Content-Type", "text/plain") - req.write("Not implemented: " + op) + req.write("Operation not implemented: " + op) return '' else: + return self._perform(op, op_method, req) + + def _perform(self, op, op_method, req): + try: val = op_method(op, req) - if isinstance(val, defer.Deferred): - val.addCallback(self._cb_perform, req, 1) - return server.NOT_DONE_YET - else: - self._cb_perform(val, req, 0) - return '' + except Exception, err: + return self._perform_err(err, req) + + if isinstance(val, defer.Deferred): + val.addCallback(self._perform_cb, req, dfr=1) + val.addErrback(self._perform_err, req, dfr=1) + return server.NOT_DONE_YET + else: + self._perform_cb(val, req, 0) + return '' - def _cb_perform(self, val, req, dfr): + def _perform_cb(self, val, req, dfr): """Callback to complete the request. May be called from a Deferred. + + @param err: the error + @param req: request causing the error + @param dfr: deferred flag """ if isinstance(val, error.ErrorPage): req.write(val.render(req)) elif self.use_sxp(req): req.setHeader("Content-Type", sxp.mime_type) - sxp.show(val, req) + sxp.show(val, out=req) else: req.write('') self.print_path(req) @@ -126,6 +141,34 @@ class SrvBase(resource.Resource): if dfr: req.finish() + def _perform_err(self, err, req, dfr=0): + """Error callback to complete a request. + May be called from a Deferred. + + @param err: the error + @param req: request causing the error + @param dfr: deferred flag + """ + if not (isinstance(err, ArgError) or + isinstance(err, sxp.ParseError) or + isinstance(err, XendError)): + if dfr: + return err + else: + raise + if self.use_sxp(req): + req.setHeader("Content-Type", sxp.mime_type) + sxp.show(['xend.err', str(err)], out=req) + else: + req.setHeader("Content-Type", "text/plain") + req.write('Error in ') + req.write(op) + req.write(': ') + req.write(str(err)) + if dfr: + req.finish() + + def print_path(self, req): """Print the path with hyperlinks. """ diff --git a/tools/python/xen/xend/server/SrvConsole.py b/tools/python/xen/xend/server/SrvConsole.py index 59d0e5f11c..eb8994425b 100644 --- a/tools/python/xen/xend/server/SrvConsole.py +++ b/tools/python/xen/xend/server/SrvConsole.py @@ -21,19 +21,22 @@ class SrvConsole(SrvDir): return self.perform(req) def render_GET(self, req): - if self.use_sxp(req): - req.setHeader("Content-Type", sxp.mime_type) - sxp.show(self.info.sxpr(), out=req) - else: - req.write('') - self.print_path(req) - #self.ls() - req.write('

%s

' % self.info) - req.write('

Connect to domain %d

' - % (self.info.uri(), self.info.dom2)) - self.form(req) - req.write('') - return '' + try: + if self.use_sxp(req): + req.setHeader("Content-Type", sxp.mime_type) + sxp.show(self.info.sxpr(), out=req) + else: + req.write('') + self.print_path(req) + #self.ls() + req.write('

%s

' % self.info) + req.write('

Connect to domain %d

' + % (self.info.uri(), self.info.dom2)) + self.form(req) + req.write('') + return '' + except Exception, ex: + self._perform_err(ex, req) def form(self, req): req.write('
' % req.prePathURL()) diff --git a/tools/python/xen/xend/server/SrvConsoleDir.py b/tools/python/xen/xend/server/SrvConsoleDir.py index 814b448370..1371f6c0ef 100644 --- a/tools/python/xen/xend/server/SrvConsoleDir.py +++ b/tools/python/xen/xend/server/SrvConsoleDir.py @@ -31,17 +31,20 @@ class SrvConsoleDir(SrvDir): return v def render_GET(self, req): - if self.use_sxp(req): - req.setHeader("Content-Type", sxp.mime_type) - self.ls_console(req, 1) - else: - req.write("") - self.print_path(req) - self.ls(req) - self.ls_console(req) - #self.form(req.wfile) - req.write("") - return '' + try: + if self.use_sxp(req): + req.setHeader("Content-Type", sxp.mime_type) + self.ls_console(req, 1) + else: + req.write("") + self.print_path(req) + self.ls(req) + self.ls_console(req) + #self.form(req.wfile) + req.write("") + return '' + except Exception, ex: + self._perform_err(ex, req) def ls_console(self, req, use_sxp=0): url = req.prePathURL() diff --git a/tools/python/xen/xend/server/SrvDaemon.py b/tools/python/xen/xend/server/SrvDaemon.py index e80b23334e..fe47592b64 100644 --- a/tools/python/xen/xend/server/SrvDaemon.py +++ b/tools/python/xen/xend/server/SrvDaemon.py @@ -31,6 +31,7 @@ from xen.xend import sxp from xen.xend import PrettyPrint from xen.xend import EventServer eserver = EventServer.instance() +from xen.xend.XendError import XendError from xen.xend.server import SrvServer @@ -114,7 +115,7 @@ class MgmtProtocol(protocol.DatagramProtocol): """ print name, req dom = sxp.child_value(req, 'domain') - if not dom: raise ValueError('Missing domain') + if not dom: raise XendError('Missing domain') dom = int(dom) console_port = sxp.child_value(req, 'console_port') if console_port: @@ -131,11 +132,11 @@ class MgmtProtocol(protocol.DatagramProtocol): def op_console_disconnect(self, name, req): id = sxp.child_value(req, 'id') if not id: - raise ValueError('Missing console id') + raise XendError('Missing console id') id = int(id) console = self.daemon.get_console(id) if not console: - raise ValueError('Invalid console id') + raise XendError('Invalid console id') if console.conn: console.conn.loseConnection() return ['ok'] @@ -340,7 +341,7 @@ class EventProtocol(protocol.Protocol): return 'op_' + name.replace('.', '_') def operror(self, name, req): - raise NotImplementedError('Invalid operation: ' +name) + raise XendError('Invalid operation: ' +name) def dispatch(self, req): op_name = sxp.name(req) @@ -371,7 +372,7 @@ class EventProtocol(protocol.Protocol): def op_console_disconnect(self, name, req): id = sxp.child_value(req, 'id') if not id: - raise ValueError('Missing console id') + raise XendError('Missing console id') self.daemon.console_disconnect(id) return ['ok'] @@ -707,7 +708,7 @@ class Daemon: """ ctrl = self.blkifCF.getInstanceByDom(dom) if not ctrl: - raise ValueError('No blkif controller: %d' % dom) + raise XendError('No blkif controller: %d' % dom) print 'blkif_dev_create>', dom, vdev, mode, segment d = ctrl.attachDevice(vdev, mode, segment, recreate=recreate) return d @@ -740,7 +741,7 @@ class Daemon: """ ctrl = self.netifCF.getInstanceByDom(dom) if not ctrl: - raise ValueError('No netif controller: %d' % dom) + raise XendError('No netif controller: %d' % dom) d = ctrl.attachDevice(vif, config, recreate=recreate) return d @@ -769,7 +770,7 @@ class Daemon: """ console = self.get_console(id) if not console: - raise ValueError('Invalid console id') + raise XendError('Invalid console id') console.disconnect() def domain_shutdown(self, dom, reason): @@ -777,7 +778,7 @@ class Daemon: """ ctrl = self.domainCF.getInstanceByDom(dom) if not ctrl: - raise ValueError('No domain controller: %d' % dom) + raise XendError('No domain controller: %d' % dom) ctrl.shutdown(reason) return 0 diff --git a/tools/python/xen/xend/server/SrvDir.py b/tools/python/xen/xend/server/SrvDir.py index c49c0b36ba..106c5ef268 100644 --- a/tools/python/xen/xend/server/SrvDir.py +++ b/tools/python/xen/xend/server/SrvDir.py @@ -1,9 +1,20 @@ # Copyright (C) 2004 Mike Wray +from twisted.protocols import http from twisted.web import error + from xen.xend import sxp +from xen.xend.XendError import XendError + from SrvBase import SrvBase +class SrvError(error.ErrorPage): + + def render(self, request): + val = error.ErrorPage.render(self, request) + request.setResponseCode(self.code, self.brief) + return val + class SrvConstructor: """Delayed constructor for sub-servers. Does not import the sub-server class or create the object until needed. @@ -38,11 +49,17 @@ class SrvDir(SrvBase): self.table = {} self.order = [] + def noChild(self, msg): + return SrvError(http.NOT_FOUND, msg, msg) + def getChild(self, x, req): if x == '': return self - val = self.get(x) + try: + val = self.get(x) + except XendError, ex: + return self.noChild(str(ex)) if val is None: - return error.NoResource('Not found') + return self.noChild('Not found ' + str(x)) else: return val @@ -59,16 +76,19 @@ class SrvDir(SrvBase): self.order.append(x) def render_GET(self, req): - if self.use_sxp(req): - req.setHeader("Content-type", sxp.mime_type) - self.ls(req, 1) - else: - req.write('') - self.print_path(req) - self.ls(req) - self.form(req) - req.write('') - return '' + try: + if self.use_sxp(req): + req.setHeader("Content-type", sxp.mime_type) + self.ls(req, 1) + else: + req.write('') + self.print_path(req) + self.ls(req) + self.form(req) + req.write('') + return '' + except Exception, ex: + self._perform_err(ex, req) def ls(self, req, use_sxp=0): url = req.prePathURL() diff --git a/tools/python/xen/xend/server/SrvDmesg.py b/tools/python/xen/xend/server/SrvDmesg.py index cadfd692e8..7580ecded7 100644 --- a/tools/python/xen/xend/server/SrvDmesg.py +++ b/tools/python/xen/xend/server/SrvDmesg.py @@ -14,16 +14,19 @@ class SrvDmesg(SrvDir): self.xd = XendDmesg.instance() def render_GET(self, req): - if self.use_sxp(req): - req.setHeader("Content-Type", sxp.mime_type) - sxp.show(['dmesg'] + self.info(), out=req) - else: - req.write('') - req.write('
')
-            self.print_path(req)
-            req.write(self.info()[0])
-            req.write('
') - return '' + try: + if self.use_sxp(req): + req.setHeader("Content-Type", sxp.mime_type) + sxp.show(['dmesg'] + self.info(), out=req) + else: + req.write('') + req.write('
')
+                self.print_path(req)
+                req.write(self.info()[0])
+                req.write('
') + return '' + except Exception, ex: + self._perform_err(ex, req) def info(self): return self.xd.info() diff --git a/tools/python/xen/xend/server/SrvDomain.py b/tools/python/xen/xend/server/SrvDomain.py index 3f01b6be97..a3ec017622 100644 --- a/tools/python/xen/xend/server/SrvDomain.py +++ b/tools/python/xen/xend/server/SrvDomain.py @@ -100,15 +100,8 @@ class SrvDomain(SrvDir): fn = FormFn(self.xd.domain_device_create, [['dom', 'int'], ['config', 'sxpr']]) - try: - d = fn(req.args, {'dom': self.dom.id}) - d.addErrback(self._op_device_create_err, req) - return d - except ValueError, ex: - return ['err', str(ex)] - - def _op_device_create_err(self, err, req): - return ['err', str(err)] + d = fn(req.args, {'dom': self.dom.id}) + return d def op_device_destroy(self, op, req): fn = FormFn(self.xd.domain_device_destroy, diff --git a/tools/python/xen/xend/server/SrvDomainDir.py b/tools/python/xen/xend/server/SrvDomainDir.py index 4c1fd4e14f..130072c871 100644 --- a/tools/python/xen/xend/server/SrvDomainDir.py +++ b/tools/python/xen/xend/server/SrvDomainDir.py @@ -9,6 +9,7 @@ from twisted.web import error from xen.xend import sxp from xen.xend import XendDomain from xen.xend.Args import FormFn +from xen.xend.XendError import XendError from SrvDir import SrvDir from SrvDomain import SrvDomain @@ -23,13 +24,10 @@ class SrvDomainDir(SrvDir): def domain(self, x): val = None - try: - dom = self.xd.domain_get(x) - if not dom: raise KeyError('No such domain') - val = SrvDomain(dom) - except KeyError, ex: - print 'SrvDomainDir>', ex - pass + dom = self.xd.domain_get(x) + if not dom: + raise XendError('No such domain ' + str(x)) + val = SrvDomain(dom) return val def get(self, x): @@ -44,6 +42,7 @@ class SrvDomainDir(SrvDir): Expects the domain config in request parameter 'config' in SXP format. """ ok = 0 + errmsg = '' try: configstring = req.args.get('config')[0] print 'config:', configstring @@ -55,12 +54,12 @@ class SrvDomainDir(SrvDir): except Exception, ex: print 'op_create> Exception in config', ex traceback.print_exc() + errmsg = 'Configuration error ' + str(ex) + except sxp.ParseError, ex: + errmsg = 'Invalid configuration ' + str(ex) if not ok: - req.setResponseCode(http.BAD_REQUEST, "Invalid configuration") - return "Invalid configuration" - return error.ErrorPage(http.BAD_REQUEST, - "Invalid", - "Invalid configuration") + req.setResponseCode(http.BAD_REQUEST, errmsg) + return errmsg try: deferred = self.xd.domain_create(config) deferred.addCallback(self._op_create_cb, configstring, req) @@ -71,10 +70,6 @@ class SrvDomainDir(SrvDir): traceback.print_exc() req.setResponseCode(http.BAD_REQUEST, "Error creating domain: " + str(ex)) return str(ex) - #return error.ErrorPage(http.BAD_REQUEST, - # "Error creating domain", - # str(ex)) - def _op_create_cb(self, dominfo, configstring, req): """Callback to handle deferred domain creation. @@ -113,7 +108,7 @@ class SrvDomainDir(SrvDir): [['file', 'str']]) deferred = fn(req.args) deferred.addCallback(self._op_restore_cb, req) - deferred.addErrback(self._op_restore_err, req) + #deferred.addErrback(self._op_restore_err, req) return deferred def _op_restore_cb(self, dominfo, req): @@ -140,17 +135,20 @@ class SrvDomainDir(SrvDir): return self.perform(req) def render_GET(self, req): - if self.use_sxp(req): - req.setHeader("Content-Type", sxp.mime_type) - self.ls_domain(req, 1) - else: - req.write("") - self.print_path(req) - self.ls(req) - self.ls_domain(req) - self.form(req) - req.write("") - return '' + try: + if self.use_sxp(req): + req.setHeader("Content-Type", sxp.mime_type) + self.ls_domain(req, 1) + else: + req.write("") + self.print_path(req) + self.ls(req) + self.ls_domain(req) + self.form(req) + req.write("") + return '' + except Exception, ex: + self._perform_err(ex, req) def ls_domain(self, req, use_sxp=0): url = req.prePathURL() diff --git a/tools/python/xen/xend/server/SrvNode.py b/tools/python/xen/xend/server/SrvNode.py index fadd32309e..e99526fabf 100644 --- a/tools/python/xen/xend/server/SrvNode.py +++ b/tools/python/xen/xend/server/SrvNode.py @@ -45,22 +45,25 @@ class SrvNode(SrvDir): return self.perform(req) def render_GET(self, req): - if self.use_sxp(req): - req.setHeader("Content-Type", sxp.mime_type) - sxp.show(['node'] + self.info(), out=req) - else: - url = req.prePathURL() - if not url.endswith('/'): - url += '/' - req.write('') - self.print_path(req) - req.write('
    ') - for d in self.info(): - req.write('
  • %10s: %s' % (d[0], str(d[1]))) - req.write('
  • Xen dmesg output') - req.write('
') - req.write('') - return '' + try: + if self.use_sxp(req): + req.setHeader("Content-Type", sxp.mime_type) + sxp.show(['node'] + self.info(), out=req) + else: + url = req.prePathURL() + if not url.endswith('/'): + url += '/' + req.write('') + self.print_path(req) + req.write('
    ') + for d in self.info(): + req.write('
  • %10s: %s' % (d[0], str(d[1]))) + req.write('
  • Xen dmesg output') + req.write('
') + req.write('') + return '' + except Exception, ex: + self._perform_err(ex, req) def info(self): return self.xn.info() diff --git a/tools/python/xen/xend/server/domain.py b/tools/python/xen/xend/server/domain.py index 683d352ec0..3a07c09b97 100644 --- a/tools/python/xen/xend/server/domain.py +++ b/tools/python/xen/xend/server/domain.py @@ -1,5 +1,7 @@ # Copyright (C) 2004 Mike Wray +from xen.xend.XendError import XendError + import channel import controller from messages import * @@ -57,6 +59,6 @@ class DomainController(controller.Controller): """ msgtype = self.reasons.get(reason) if not msgtype: - raise ValueError('invalid reason:' + reason) + raise XendError('invalid reason:' + reason) msg = packMsg(msgtype, {}) self.writeRequest(msg) diff --git a/tools/python/xen/xend/server/netif.py b/tools/python/xen/xend/server/netif.py index 894dc85832..1cbbe67ec8 100755 --- a/tools/python/xen/xend/server/netif.py +++ b/tools/python/xen/xend/server/netif.py @@ -8,6 +8,7 @@ from twisted.internet import defer from xen.xend import sxp from xen.xend import PrettyPrint from xen.xend import Vifctl +from xen.xend.XendError import XendError import channel import controller @@ -123,9 +124,9 @@ class NetDev(controller.Dev): self.ipaddr = None vmac = sxp.child_value(config, 'mac') - if not vmac: raise ValueError("invalid mac") + if not vmac: raise XendError("invalid mac") mac = [ int(x, 16) for x in vmac.split(':') ] - if len(mac) != 6: raise ValueError("invalid mac") + if len(mac) != 6: raise XendError("invalid mac") self.mac = mac self.bridge = sxp.child_value(config, 'bridge') -- 2.30.2